/**
 * Copyright (c) 2009 blurredVision
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
 * associated documentation files (the "Software"), to deal in the Software without restriction, 
 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or 
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT 
 * NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT 
 * OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include "StdAfx.h"
#include "Light.h"
#include "ResourceFactory.h"
#include "core/core.h"

namespace directx {

int DXLight::iLightCounter = 0;

DXLight::DXLight(void)
{
	ZeroMemory( &m_dxLight, sizeof(D3DLIGHT9) );
}

DXLight::~DXLight(void)
{
}

void DXLight::reset()
{
	DXResource::reset();

	// Get the d3dDevice -> see DXResource
	ZeroMemory( &m_dxLight, sizeof(D3DLIGHT9) );
}

void DXLight::release()
{
}


void DXLight::draw()
{
	HRESULT hr;

	if (FAILED( hr = pd3dDevice->SetLight( iLightCounter, &m_dxLight ) ))
	{
		coreGetLog()->WriteError("Could not set DXLight " + iLightCounter, __FILE__, __LINE__);
		return;
	}

	if (FAILED( hr = pd3dDevice->LightEnable( iLightCounter, TRUE ) ))
	{
		coreGetLog()->WriteError("Could not enable DXLight " + iLightCounter, __FILE__, __LINE__);
		return;
	}

	// Enable the DXLight and set the render states
	if (iLightCounter == 0) {
		if (FAILED( hr = pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE ) ))
		{
			coreGetLog()->WriteError("Could not enable lighting in rendering state", __FILE__, __LINE__);
			return;
		}

		// TODO move to Renderer
		if (FAILED( hr = pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0x00101010 ) ))
		{
			coreGetLog()->WriteError("Could not enable ambient lighting", __FILE__, __LINE__);
			return;
		}

	}

	iLightCounter++;
}

void DXLight::setValues()
{
	D3DXVECTOR3 vecDir;	

	switch ( getLightType() ) {
		case LIGHT_DIRECTIONAL:
			m_dxLight.Type = D3DLIGHT_DIRECTIONAL;
			vecDir.x = getDirection().x;
			vecDir.y = getDirection().y;
			vecDir.z = getDirection().z;
			D3DXVec3Normalize( (D3DXVECTOR3*)&m_dxLight.Direction, &vecDir );
			break;
		case LIGHT_SPOT:
		case LIGHT_POINT:
			m_dxLight.Type = D3DLIGHT_POINT;
			m_dxLight.Position.x = getPosition().x;
			m_dxLight.Position.y = getPosition().y;
			m_dxLight.Position.z = getPosition().z;
			m_dxLight.Attenuation0 = 100.0;
			break;
		default:
			coreGetLog()->WriteError("No DXLight type set", __FILE__, __LINE__);
			m_dxLight.Type = D3DLIGHT_DIRECTIONAL;
			break;
	}

	// Set the diffuse color of the DXLight
	m_dxLight.Diffuse.r = getDiffuseColor().x;
	m_dxLight.Diffuse.g = getDiffuseColor().y;
	m_dxLight.Diffuse.b = getDiffuseColor().z;
	m_dxLight.Diffuse.a = 1;

	m_dxLight.Ambient.r = getAmbientColor().x;
	m_dxLight.Ambient.g = getAmbientColor().y;
	m_dxLight.Ambient.b = getAmbientColor().z;
	m_dxLight.Ambient.a = 1;

	m_dxLight.Specular.r = getSpecularColor().x;
	m_dxLight.Specular.g = getSpecularColor().y;
	m_dxLight.Specular.b = getSpecularColor().z;
	m_dxLight.Specular.a = 1;

	// Set the range of the DXLight
	m_dxLight.Range = getRange().x;
}

} // namespace

